package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.constant.JiGuangConstant;
import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.constant.Constant;
import com.csun.cmny.provider.dao.OmcOrderMapper;
import com.csun.cmny.provider.dto.OrderDto;
import com.csun.cmny.provider.dto.OrderQueryDto;
import com.csun.cmny.provider.exceptions.OmcBizException;
import com.csun.cmny.provider.model.domain.OmcOrder;
import com.csun.cmny.provider.model.domain.OmcService;
import com.csun.cmny.provider.model.enums.UacRoleCodeEnum;
import com.csun.cmny.provider.model.vo.GroupVo;
import com.csun.cmny.provider.model.vo.RpcRoleVo;
import com.csun.cmny.provider.model.vo.RpcUserVo;
import com.csun.cmny.provider.model.vo.VolunteerVo;
import com.csun.cmny.provider.pojo.Oldman;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.JPushService;
import com.csun.cmny.provider.vo.MyCommentVo;
import com.csun.cmny.provider.vo.OrderDetailVo;
import com.csun.cmny.provider.vo.OrderTaskVo;
import com.csun.cmny.provider.vo.OrderVo;
import com.csun.cmny.util.DateUtil;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jline.internal.Log;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-05-29 15:00
 * @Description: the class omc order service impl
 */
@Slf4j
@Data
@Service
@Transactional
public class OmcOrderServiceImpl extends BaseService<OmcOrder> implements OmcOrderService {

    @Resource
    private UacRpcService uacRpcService;

    @Resource
    private OmcOrderMapper omcOrderMapper;

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private HistoryService historyService;

    @Resource
    private OmcActivitiService omcActivitiService;

    @Resource
    private OmcServiceService omcServiceService;

    @Resource
    private OldmanService oldmanService;

    @Resource
    private JPushService jpushService;

    /**
     * 下单
     *
     * @param orderDto     order dto
     * @param loginAuthDto login auth dto
     * @return the int.
     */
    @Override
    public Integer orderApply(OrderDto orderDto, LoginAuthDto loginAuthDto) {

        // 校验服务是否存在
        OmcService omcService = omcServiceService.selectByKey(orderDto.getServiceId());
        if (PublicUtil.isEmpty(omcService)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032012);
        }

        // 校验下单人是否合法 (多个使用,分割)

        // 校验接单人是否合法 (多个使用,分割)
        String orderRecv = omcService.getOrderRecv();
//        if (PublicUtil.isEmpty(orderRecv)) {
//            throw new OmcBizException(ErrorCodeEnum.OMC10032017);
//        }
//        if (PublicUtil.isEmpty(UacRoleCodeEnum.getName(orderRecv))) {
//            throw new OmcBizException(ErrorCodeEnum.OMC10032018);
//        }

        // 校验确认人是否合法 (多个使用,分割)
        String orderConfirm = omcService.getOrderConfirm();

        // 校验当前用户时候可以下单该服务
        // TODO 带校验
        //omcService.getOrderPut();

        // 校验服务时间是否为合法
        if (orderDto.getServiceTime().compareTo(new Date()) < 0) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032004);
        }

        // 校验超时时间
        String durationRecv = omcService.getDurationRecv();
        if (PublicUtil.isEmpty(durationRecv)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032013);
        }

        // 校验签到超时时间
        String durationCheckIn = omcService.getDurationIn();
        if (PublicUtil.isEmpty(durationCheckIn)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032014);
        }

        // 校验签退超时时间
        String durationCheckOut = omcService.getDurationOut();
        if (PublicUtil.isEmpty(durationCheckOut)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032015);
        }

        // 校验确认超时时间
        String durationConfirm = omcService.getDurationConfirm();
        if (PublicUtil.isEmpty(durationConfirm)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032016);
        }

        // 根据Id查询老人信息
        Oldman oldman = new Oldman();
        long oldmanId = orderDto.getOldmanId();
        oldman.setOldmanId((int)oldmanId);
        oldman = oldmanService.selectByOld(oldman);
        if (PublicUtil.isEmpty(oldman)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10031017, oldmanId);
        }

        // 启动服务订单流程
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put(Constant.VAR_ORDER_SERVICE_TIME, DateUtil.dateToIsoStr(orderDto.getServiceTime()));
        // variables.put(Constant.VAR_ORDER_RECV, UacRoleCodeEnum.VOLUNTEER.getCode());
        variables.put(Constant.VAR_ORDER_RECV, orderRecv);
        variables.put(Constant.VAR_ORDER_RECV_DURATION, String.format(Constant.ISO8601_PTM, durationRecv));
        variables.put(Constant.VAR_ORDER_CHECK_IN_DURATION, String.format(Constant.ISO8601_PTM, durationCheckIn));
        variables.put(Constant.VAR_ORDER_CHECK_OUT_DURATION, String.format(Constant.ISO8601_PTM, durationCheckOut));
        variables.put(Constant.VAR_ORDER_CONFIRM_DURATION, String.format(Constant.ISO8601_PTM, durationConfirm));
        variables.put(Constant.VAR_ORDER_PUT_USER, loginAuthDto.getUserId().toString());
        variables.put(Constant.VAR_ORDER_CONFIRM, orderConfirm);

        ProcessInstance processInstance = omcActivitiService
                .startProcessInstanceByKeyAndTenantId(Constant.PROCESS_KEY_ORDER, variables, loginAuthDto.getGroupId());

        // 查询当前任务
        Task task = omcActivitiService.getTaskByProcessInstanceId(processInstance.getProcessInstanceId());

        // 添加批注
        omcActivitiService.addTaskComment(task, loginAuthDto.getUserName() + "[管理员]", "下单");

        // 完成下单
        omcActivitiService.completeTask(task);

        OmcOrder omcOrder = new OmcOrder();
        BeanUtils.copyProperties(orderDto, omcOrder);

        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setUserIdPut(loginAuthDto.getUserId());
        omcOrder.setUserNamePut(loginAuthDto.getUserName());
        omcOrder.setOldmanName(oldman.getOldName());
        omcOrder.setOldPhone(oldman.getOldPhone());
        omcOrder.setOldAddress(oldman.getOldAddress());
        omcOrder.setProcessInstanceId(processInstance.getProcessInstanceId());
        omcOrder.setStat(Constant.ORDER_STAT_PUT);

        // 更新服务下单次数
        // TODO
        OmcService newOmcService = new OmcService();
        newOmcService.setId(omcService.getId());
        newOmcService.setOrderTimes(omcService.getOrderTimes() + 1);
        omcServiceService.update(newOmcService);

        return omcOrderMapper.insertSelective(omcOrder);
    }

    /**
     * 取消订单
     *
     * @param id 订单Id
     * @return the int.
     */
    @Override
    public Integer orderCancelById(Long id, LoginAuthDto loginAuthDto) {

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        // 下单人才能取消订单
        if (!loginAuthDto.getUserId().equals(omcOrderQuery.getUserIdPut())) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032006);
        }

        String processInstanceId = omcOrderQuery.getProcessInstanceId();
        // 查询流程实例是否存在
        if (PublicUtil.isNotEmpty(processInstanceId)) {
            String deleteReason = String.format("[%s]取消下单", loginAuthDto.getUserName());
            Task task = taskService.createTaskQuery()
                    .processInstanceId(processInstanceId).singleResult();
            if (PublicUtil.isEmpty(task)) {
                throw new OmcBizException(ErrorCodeEnum.OMC10032019);
            }
            Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[管理员]");
            taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_WAIT);
            omcActivitiService.deleteProcessInstance(processInstanceId, deleteReason);
        }

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setStat(Constant.ORDER_STAT_CANCEL);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    /**
     * 查询订单列表
     *
     * @param orderQueryDto order query dto
     * @return the page info.
     */
    @Override
    public PageInfo queryOrderListWithPage(OrderQueryDto orderQueryDto) {

        PageHelper.startPage(orderQueryDto.getPageNum(), orderQueryDto.getPageSize());
        List<OrderVo> orderVoList = omcOrderMapper.queryOrderListWithPage(orderQueryDto);

        //List<Long> userList = orderVoList.stream().map(OrderVo::getUserIdGet).filter(x -> x !=null ).distinct().collect(Collectors.toList());

        // 查询接单人信息(志愿者)
        // List<VolunteerVo> volunteerVoList = uacRpcService.queryVolunteerListByVolunteerIds(volunteerList);
        //List<RpcUserVo> rpcUserVoList = uacRpcService.queryUserListByUserIds(userList);

        // list 转 map
        //Map<Long, RpcUserVo> rpcUserVoMap = rpcUserVoList.stream().collect(Collectors.toMap(RpcUserVo::getId, Function.identity()));

//        for (OrderVo o : orderVoList) {
//            if (PublicUtil.isNotEmpty(o.getUserIdGet())) {
//                RpcUserVo u = rpcUserVoMap.get(o.getUserIdGet());
//                o.setUserNameGet(u.getUserName());
//            }
//        }

        return new PageInfo<>(orderVoList);
    }

    /**
     * 查询订单任务列表
     *
     * @param orderQueryDto order query dto
     * @param loginAuthDto  login auth dto
     * @return
     */
    @Override
    public PageInfo showOrderTask(OrderQueryDto orderQueryDto, LoginAuthDto loginAuthDto) {

        // 计算指定页index
        Integer firstIndex = (orderQueryDto.getPageNum() - 1) * orderQueryDto.getPageSize();

        return null;
    }

    /**
     * 等待接单任务列表
     *
     * @param loginAuthDto
     * @return
     */
    @Override
    public List<OrderTaskVo> showOrderWaitRecvTask(LoginAuthDto loginAuthDto) {

        // 获取当前用户角色
        List<RpcRoleVo> roleVoList = uacRpcService.queryRoleListByUserId(loginAuthDto.getUserId());
        List<String> roleCodeList = roleVoList.stream().map(r -> r.getRoleCode()).collect(Collectors.toList());

        List<OrderTaskVo> orderTaskVos = Lists.newArrayList();

        List<Task> taskList = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .taskCandidateGroupIn(roleCodeList)
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .taskName(Constant.ORDER_TASK_NAME_RECV)
                .orderByTaskCreateTime()
                .desc().list();

        if (PublicUtil.isEmpty(taskList)) {
            return null;
        }

        // 获取所有订单信息
        List<String> processInstanceIds =
                taskList.stream().map(t -> t.getProcessInstanceId()).collect(Collectors.toList());

        List<OrderVo> orderVoList = omcOrderMapper.queryOrderListByProcessInstanceIds(processInstanceIds);
        Map<String, OrderVo> orderVoMap = orderVoList.stream().collect(Collectors.toMap(OrderVo::getProcessInstanceId, Function.identity()));

        for (Task t : taskList) {
            OrderVo orderVo = orderVoMap.get(t.getProcessInstanceId());
            OrderTaskVo orderTaskVo = new OrderTaskVo();
            BeanUtils.copyProperties(orderVo, orderTaskVo);
            BeanUtils.copyProperties(t, orderTaskVo);

            Date createTime = t.getCreateTime();
            long time = 0;
            switch (t.getName()) {
                case Constant.ORDER_TASK_NAME_RECV :
                    time = 60 * 1000 * Integer.parseInt(orderVo.getDurationRecv());
                    break;
            }
            orderTaskVo.setStartTime(createTime);
            orderTaskVo.setEndTime(new Date(createTime.getTime() + time));

            orderTaskVo.setTaskId(t.getId());
            orderTaskVos.add(orderTaskVo);
        }

        return orderTaskVos;
    }

    /**
     * 待接单处理
     *
     * @param processInstanceId
     */
    @Override
    public void orderWaitByProcessInstanceId(String processInstanceId) {

        updateStatByProcessInstanceId(Constant.ORDER_STAT_WAIT, processInstanceId);
    }

    /**
     * 接单超时处理
     *
     * @param processInstanceId
     */
    @Override
    public void orderRecvDelayByProcessInstanceId(String processInstanceId) {

        updateStatByProcessInstanceId(Constant.ORDER_STAT_RECV_DELAY, processInstanceId);
    }

    /**
     * 签到超时处理
     *
     * @param processInstanceId
     */
    @Override
    public void orderCheckInDelayByProcessInstanceId(String processInstanceId) {

        updateStatByProcessInstanceId(Constant.ORDER_STAT_CHECK_IN_DELAY, processInstanceId);
    }

    /**
     * 签退超时处理
     *
     * @param processInstanceId
     */
    @Override
    public void orderCheckOutDelayByProcessInstanceId(String processInstanceId) {

        updateStatByProcessInstanceId(Constant.ORDER_STAT_CHECK_OUT_DELAY, processInstanceId);
    }

    /**
     * 确认超时处理
     *
     * @param processInstanceId
     */
    @Override
    public void orderConfirmDelayByProcessInstanceId(String processInstanceId) {

        updateStatByProcessInstanceId(Constant.ORDER_STAT_CONFIRM_DELAY, processInstanceId);

        // 订单完成处理
        orderCompleteByProcessInstanceId(processInstanceId);
    }

    /**
     * 查询待服务任务
     *
     * @param loginAuthDto
     * @return
     */
    @Override
    public List<OrderTaskVo> showOrderWaitServiceTask(LoginAuthDto loginAuthDto) {

        List<OrderTaskVo> orderTaskVos = Lists.newArrayList();

        List<String> taskNameList = Lists.newArrayList();
        taskNameList.add(Constant.ORDER_TASK_NAME_CHECK_IN);
        taskNameList.add(Constant.ORDER_TASK_NAME_CHECK_OUT);

        List<Task> taskList = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .taskAssignee(loginAuthDto.getUserId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .taskNameIn(taskNameList)
                .orderByTaskCreateTime()
                .desc().list();

        if (PublicUtil.isEmpty(taskList)) {
            return null;
        }

        // 获取所有订单信息
        List<String> processInstanceIds =
                taskList.stream().map(t -> t.getProcessInstanceId()).collect(Collectors.toList());

        List<OrderVo> orderVoList = omcOrderMapper.queryOrderListByProcessInstanceIds(processInstanceIds);
        Map<String, OrderVo> orderVoMap = orderVoList.stream().collect(Collectors.toMap(OrderVo::getProcessInstanceId, Function.identity()));

        for (Task t : taskList) {
            OrderVo orderVo = orderVoMap.get(t.getProcessInstanceId());
            OrderTaskVo orderTaskVo = new OrderTaskVo();
            BeanUtils.copyProperties(orderVo, orderTaskVo);
            BeanUtils.copyProperties(t, orderTaskVo);

            Date createTime = t.getCreateTime();
            long time = 0;
            switch (t.getName()) {
                case Constant.ORDER_TASK_NAME_CHECK_IN :
                    time = 60 * 1000 * Integer.parseInt(orderVo.getDurationIn());
                    break;
                case Constant.ORDER_TASK_NAME_CHECK_OUT :
                    time = 60 * 1000 * Integer.parseInt(orderVo.getDurationOut());
                    break;
            }
            orderTaskVo.setStartTime(createTime);
            orderTaskVo.setEndTime(new Date(createTime.getTime() + time));

            orderTaskVo.setTaskId(t.getId());
            orderTaskVos.add(orderTaskVo);
        }

        return orderTaskVos;
    }

    /**
     * 签到
     *
     * @param id           id
     * @param loginAuthDto login auth dto
     * @return
     */
    @Override
    public Integer orderCheckInById(Long id, LoginAuthDto loginAuthDto) {

        Long userId = loginAuthDto.getUserId();
        String processInstanceId;

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        // 接单人才能签到
        if (!userId.equals(omcOrderQuery.getUserIdGet())) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032010);
        }

        processInstanceId = omcOrderQuery.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .taskAssignee(userId.toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .processInstanceId(processInstanceId)
                .taskName(Constant.ORDER_TASK_NAME_CHECK_IN)
                .singleResult();

        if (PublicUtil.isEmpty(task)) {
            Log.error("签到任务不存在, 无法签到");
            throw new OmcBizException(ErrorCodeEnum.OMC10032008);
        }

        // Map<String,Object> variables = new HashMap<String,Object>();
        // variables.put(Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_CHECK_IN);

        taskService.setVariable(task.getId(), Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_CHECK_IN);

        // 设置用户id
        Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[志愿者]");
        // 添加批注信息
        taskService.addComment(task.getId(), processInstanceId, "签到");
        // 完成任务
        taskService.complete(task.getId());

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setUserIdGet(userId);
        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setStat(Constant.ORDER_STAT_CHECK_IN);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    /**
     * 签退
     *
     * @param id           id
     * @param loginAuthDto login auth dto
     * @return
     */
    @Override
    public Integer orderCheckOutById(Long id, LoginAuthDto loginAuthDto) {

        Long userId = loginAuthDto.getUserId();
        String processInstanceId;

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        // 接单人才能签退
        if (!userId.equals(omcOrderQuery.getUserIdGet())) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032009);
        }

        processInstanceId = omcOrderQuery.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .taskAssignee(userId.toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .processInstanceId(processInstanceId)
                .taskName(Constant.ORDER_TASK_NAME_CHECK_OUT)
                .singleResult();

        if (PublicUtil.isEmpty(task)) {
            Log.error("签退任务不存在, 无法接单");
            /**
             * @date    2019-09-04
             * @author  chisj
             * @desc    提示信息未【订单不存在】
             */
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        //Map<String,Object> variables = new HashMap<String,Object>();
        //variables.put(Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_WAIVE);

        // 设置用户id
        Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[志愿者]");
        // 添加批注信息
        taskService.addComment(task.getId(), processInstanceId, "签退");
        // 完成任务
        taskService.complete(task.getId());

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setUserIdGet(userId);
        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setStat(Constant.ORDER_STAT_CHECK_OUT);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    /**
     * 接单
     *
     * @param id           id
     * @param loginAuthDto login auth dto
     * @return
     */
    @Override
    public Integer orderRecvById(Long id, LoginAuthDto loginAuthDto) {

        Long userId = loginAuthDto.getUserId();
        String processInstanceId;

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        // 接单人才能取消订单
//        if (!userId.equals(omcOrderQuery.getUserIdPut())) {
//            throw new OmcBizException(ErrorCodeEnum.OMC10032006);
//        }

        // 获取当前用户角色
        List<RpcRoleVo> roleVoList = uacRpcService.queryRoleListByUserId(loginAuthDto.getUserId());
        List<String> roleCodeList = roleVoList.stream().map(r -> r.getRoleCode()).collect(Collectors.toList());

        processInstanceId = omcOrderQuery.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                //.taskAssignee(userId.toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .taskCandidateGroupIn(roleCodeList)
                .processInstanceId(processInstanceId)
                .taskName(Constant.ORDER_TASK_NAME_RECV)
                .singleResult();

        if (PublicUtil.isEmpty(task)) {
            Log.error("接单任务不存在, 无法接单");
            throw new OmcBizException(ErrorCodeEnum.OMC10032008);
        }

        //Map<String,Object> variables = task.getProcessVariables();
        //variables.put(Constant.VAR_ORDER_GET_USER, "99");
        //runtimeService.setVariable();
        try {
            taskService.setVariable(task.getId(), Constant.VAR_ORDER_GET_USER, userId.toString());

            // 设置用户id
            Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[志愿者]");
            // 添加批注信息
            taskService.addComment(task.getId(), processInstanceId, "接单");

            // 完成任务
            taskService.complete(task.getId());
        } catch (Exception e) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032021);
        }

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setUserIdGet(userId);
        omcOrder.setUserNameGet(loginAuthDto.getUserName());
        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setStat(Constant.ORDER_STAT_RECV);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    /**
     * 确认
     *
     * @param id           id
     * @param loginAuthDto login auth dto
     * @return
     */
    @Override
    public Integer orderConfirmById(Long id, LoginAuthDto loginAuthDto) {

        Long userId = loginAuthDto.getUserId();
        String processInstanceId;

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        processInstanceId = omcOrderQuery.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                //.taskAssigneeLike(userId.toString())
                .taskAssignee(userId.toString())
                //.taskCandidateGroup(UacRoleCodeEnum.VOLUNTEER.getCode())
                .processInstanceId(processInstanceId)
                .taskName(Constant.ORDER_TASK_NAME_CONFIRM)
                .singleResult();

        if (PublicUtil.isEmpty(task)) {
            Log.error("确认任务不存在, 无法确认");
            throw new OmcBizException(ErrorCodeEnum.OMC10032008);
        }

        // Map<String,Object> variables = new HashMap<String,Object>();
        // variables.put(Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_WAIVE);

        // 设置用户id
        Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[管理员]");
        // 添加批注信息
        taskService.addComment(task.getId(), processInstanceId, "确认");
        // 完成任务
        taskService.complete(task.getId());

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setStat(Constant.ORDER_STAT_CONFIRM);

        // 订单完成
        orderComplete(omcOrderQuery);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    /**
     * 查询订单详情
     *
     * @param id id
     * @return the order detail vo
     */
    @Override
    public OrderDetailVo showOrderById(Long id, LoginAuthDto loginAuthDto) {

        OrderDetailVo orderDetailVo = omcOrderMapper.showOrderById(id);
        if (PublicUtil.isEmpty(orderDetailVo)
                || PublicUtil.isEmpty(orderDetailVo.getProcessInstanceId())) {
            return null;
        }

//        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
//                .processInstanceId(orderDetailVo.getProcessInstanceId()).list();

        List<MyCommentVo> lists = Lists.newArrayList();
        List<Comment> commentList = taskService
                .getProcessInstanceComments(orderDetailVo.getProcessInstanceId());

        for (Comment c : commentList) {
            MyCommentVo m = new MyCommentVo();
            BeanUtils.copyProperties(c, m);

            lists.add(m);
        }

        long time = 0;
        //String message = commentList.get(0).getFullMessage();
        Date startTime = commentList.get(0).getTime();

        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .processInstanceId(orderDetailVo.getProcessInstanceId())
                .singleResult();

        if (PublicUtil.isNotEmpty(task)) {
            switch (task.getName()) {
                case Constant.ORDER_TASK_NAME_APPLY :
                    break;
                case Constant.ORDER_TASK_NAME_RECV :
                    startTime = task.getCreateTime();
                    time = 60 * 1000 * Integer.parseInt(orderDetailVo.getDurationRecv());
                    break;
                case Constant.ORDER_TASK_NAME_CHECK_IN :
                    time = 60 * 1000 * Integer.parseInt(orderDetailVo.getDurationIn());
                    break;
                case Constant.ORDER_TASK_NAME_CHECK_OUT :
                    time = 60 * 1000 * Integer.parseInt(orderDetailVo.getDurationOut());
                    break;
                case Constant.ORDER_TASK_NAME_CONFIRM :
                    time = 60 * 1000 * Integer.parseInt(orderDetailVo.getDurationConfirm());
                    break;
            }
        }

        orderDetailVo.setEndTime(new Date(startTime.getTime() + time));
        orderDetailVo.setLists(lists);

        return orderDetailVo;
    }

    /**
     * 查询已经完成的任务列表
     *
     * @param loginAuthDto
     * @return
     */
    @Override
    public List<OrderVo> showOrderHisFnsd(LoginAuthDto loginAuthDto) {

        // 获取当前用户角色
        // List<RpcRoleVo> roleVoList = uacRpcService.queryRoleListByUserId(loginAuthDto.getUserId());
        // List<String> roleCodeList = roleVoList.stream().map(r -> r.getRoleCode()).collect(Collectors.toList());
//        List<OrderTaskVo> orderTaskVos = Lists.newArrayList();
//
//        List<HistoricTaskInstance> histList = historyService.createHistoricTaskInstanceQuery()
//                .taskTenantId(loginAuthDto.getGroupId().toString())
//                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
//                .taskAssignee(loginAuthDto.getUserId().toString())
//                .processFinished()
//                .finished()
//                .orderByTaskCreateTime()
//                .desc()
//                .list();
//
//        if (PublicUtil.isEmpty(histList)) {
//            return null;
//        }
//
//        List<HistoricTaskInstance> distinctList = histList.stream().collect(
//                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getProcessInstanceId()))),
//                        ArrayList::new));
//
//
//        // 获取所有订单信息
//        List<String> processInstanceIds =
//                distinctList.stream().map(t -> t.getProcessInstanceId()).collect(Collectors.toList());
//
//        List<OrderVo> orderVoList = omcOrderMapper.queryOrderListByProcessInstanceIds(processInstanceIds);
//        Map<String, OrderVo> orderVoMap = orderVoList.stream().collect(Collectors.toMap(OrderVo::getProcessInstanceId, Function.identity()));
//
//        for (HistoricTaskInstance t : distinctList) {
//            OrderVo orderVo = orderVoMap.get(t.getProcessInstanceId());
//            OrderTaskVo orderTaskVo = new OrderTaskVo();
//            BeanUtils.copyProperties(orderVo, orderTaskVo);
//            BeanUtils.copyProperties(t, orderTaskVo);
//            orderTaskVo.setTaskId(t.getId());
//            orderTaskVos.add(orderTaskVo);
//        }

        List<Integer> statList = Lists.newArrayList();
        statList.add(Constant.ORDER_STAT_CHECK_IN_DELAY);
        statList.add(Constant.ORDER_STAT_CHECK_OUT_DELAY);
        statList.add(Constant.ORDER_STAT_CONFIRM);
        statList.add(Constant.ORDER_STAT_CONFIRM_DELAY);
        statList.add(Constant.ORDER_STAT_CANCEL);

        List<OrderVo> orderVoList = omcOrderMapper.showOrderHisFnsd(loginAuthDto.getUserId(), statList);

        return orderVoList;
    }
    //查询服务时长
    @Override
    public Integer selectServiceTime(Long groupId) {
        /**
         * @date    2021-11-19
         * @author  chisj
         * @desc    获取子机构id集合
         */
        List<GroupVo> groupVoList = uacRpcService.queryGroupListByGroupId(groupId);
        if (PublicUtil.isEmpty(groupVoList)) {
            return new Integer(0);
        }

        List<Long> groupIdList = Lists.newArrayList();
        for (GroupVo gv : groupVoList) {
            groupIdList.add(gv.getId());
        }
        return omcOrderMapper.selectServiceTime(groupIdList);
    }

    /**
     * 取消接单
     *
     * @param id
     * @return
     */
    @Override
    public Integer orderWaiveById(Long id, LoginAuthDto loginAuthDto) {

        Long userId = loginAuthDto.getUserId();
        String processInstanceId;

        // 查询订单是否存在
        OmcOrder omcOrderQuery = omcOrderMapper.selectByPrimaryKey(id);
        if (PublicUtil.isEmpty(omcOrderQuery)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032005);
        }

        // 接单人才能取消接单
        if (!userId.equals(omcOrderQuery.getUserIdGet())) {
            throw new OmcBizException(ErrorCodeEnum.OMC10032011);
        }

        processInstanceId = omcOrderQuery.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .taskTenantId(loginAuthDto.getGroupId().toString())
                .processDefinitionKey(Constant.PROCESS_KEY_ORDER)
                .taskAssignee(userId.toString())
                .processInstanceId(processInstanceId)
                .taskName(Constant.ORDER_TASK_NAME_CHECK_IN)
                .singleResult();

        if (PublicUtil.isEmpty(task)) {
            Log.error("签到任务不存在, 无法取消接单");
            throw new OmcBizException(ErrorCodeEnum.OMC10032008);
        }

        // Map<String,Object> variables = new HashMap<String,Object>();
        // variables.put(Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_WAIVE);
        taskService.setVariable(task.getId(), Constant.VAR_ORDER_MSG, Constant.VAR_ORDER_MSG_WAIVE);

        // 设置用户id
        Authentication.setAuthenticatedUserId(loginAuthDto.getUserName() + "[志愿者]");
        // 添加批注信息
        taskService.addComment(task.getId(), processInstanceId, "取消接单");
        // 完成任务
        taskService.complete(task.getId());

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setId(id);
        omcOrder.setUpdateInfo(loginAuthDto);
        omcOrder.setStat(Constant.ORDER_STAT_WAIVE);

        OmcService omcService = omcServiceService.selectByKey(omcOrderQuery.getServiceId());

        // 推送可以接单了
        Map<String, Object> map = Maps.newHashMap();
        List<String> tagList = Lists.newArrayList();
        tagList.add(JiGuangConstant.TAG_VOLUNTEER);
        log.info("-----chisj: recv order tagList = {}", tagList);
        // 推送 -- 可以接单了
        map.put("msgType", "orderUpdate");
        map.put("oldmanName", omcOrderQuery.getOldmanName());
        map.put("serviceName", omcService.getServiceName());
        map.put("serviceAddress", omcOrderQuery.getServiceAddress());
        jpushService.sendToAll(Constant.ORDER_MESSAGE_WAIT,
                Constant.ORDER_MESSAGE_WAIT,
                Constant.ORDER_MESSAGE_WAIT, JSONObject.fromObject(map).toString(), tagList);

        return omcOrderMapper.updateByPrimaryKeySelective(omcOrder);
    }

    public Integer updateStatByProcessInstanceId(Integer stat, String processInstanceId) {

        Example example = new Example(OmcOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("processInstanceId", processInstanceId);

        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setStat(stat);
        omcOrder.setUpdateTime(new Date());

        return omcOrderMapper.updateByExampleSelective(omcOrder, example);
    }

    public void orderCompleteByProcessInstanceId(String processInstanceId) {

        OmcOrder omcOrderQuery = new OmcOrder();
        omcOrderQuery.setProcessInstanceId(processInstanceId);
        omcOrderQuery = omcOrderMapper.selectOne(omcOrderQuery);

        orderComplete(omcOrderQuery);
    }

    /**
     * 完成订单
     *
     * @param omcOrder  omc order
     */
    public void orderComplete(OmcOrder omcOrder) {

        Integer result = -1;

        // 增加服务的服务次数
        OmcService omcService = omcServiceService.selectByKey(omcOrder.getServiceId());

        OmcService newOmcService = new OmcService();
        newOmcService.setId(omcService.getId());
        newOmcService.setOrderTimes(omcService.getServiceTimes() + 1);
        omcServiceService.update(newOmcService);

        // 校验志愿者是否存在
        VolunteerVo volunteerVo = uacRpcService.getVolunteerByUserId(omcOrder.getUserIdGet());
        if (PublicUtil.isEmpty(volunteerVo)) {
            throw new OmcBizException(ErrorCodeEnum.UAC10018002);
        }

        // 增加志愿者服务积分
        Integer integral = volunteerVo.getIntegral() + omcOrder.getIntegral();
        result = uacRpcService.updateVolunteerIntegralByVolunteerId(volunteerVo.getId(), integral);
        if (result < 1) {
            // 增加积分失败
            throw new OmcBizException(ErrorCodeEnum.OMC10031023);
        }

        // 增加志愿者服务次数
    }
}
